/**
 * Copyright 2012 Netflix, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.netflix.hystrix.contrib.javanica.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * This annotation used to specify some methods which should be processes as
 * hystrix commands.
 */
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface HystrixCommand {

	/**
	 * The command group key is used for grouping together commands such as for
	 * reporting, alerting, dashboards or team/library ownership.
	 * <p/>
	 * default => the runtime class name of annotated method
	 *
	 * @return group key
	 */
	String groupKey() default "";

	/**
	 * Hystrix command key.
	 * <p/>
	 * default => the name of annotated method. for example: <code>
	 *     ...
	 *     &#64;HystrixCommand
	 *     public User getUserById(...)
	 *     ...
	 *     the command name will be: 'getUserById'
	 * </code>
	 *
	 * @return command key
	 */
	String commandKey() default "";

	/**
	 * The thread-pool key is used to represent a HystrixThreadPool for
	 * monitoring, metrics publishing, caching and other such uses.
	 *
	 * @return thread pool key
	 */
	String threadPoolKey() default "";

	/**
	 * Specifies a method to process fallback logic. A fallback method should be
	 * defined in the same class where is HystrixCommand. Also a fallback method
	 * should have same signature to a method which was invoked as hystrix
	 * command. for example: <code>
	 *      &#64;HystrixCommand(fallbackMethod = "getByIdFallback")
	 *      public String getById(String id) {...}
	 *
	 *      private String getByIdFallback(String id) {...}
	 * </code> Also a fallback method can be annotated with
	 * {@link HystrixCommand}
	 * <p/>
	 * default => see
	 * {@link com.netflix.hystrix.contrib.javanica.command.GenericCommand#getFallback()}
	 *
	 * @return method name
	 */
	String fallbackMethod() default "";

	/**
	 * Specifies command properties.
	 *
	 * @return command properties
	 */
	HystrixProperty[] commandProperties() default {};

	/**
	 * Specifies thread pool properties.
	 *
	 * @return thread pool properties
	 */
	HystrixProperty[] threadPoolProperties() default {};

	/**
	 * Defines exceptions which should be ignored. Optionally these can be
	 * wrapped in HystrixRuntimeException if raiseHystrixExceptions contains
	 * RUNTIME_EXCEPTION.
	 *
	 * @return exceptions to ignore
	 */
	Class<? extends Throwable>[] ignoreExceptions() default {};

	/**
	 * Specifies the mode that should be used to execute hystrix observable
	 * command. For more information see {@link ObservableExecutionMode}.
	 *
	 * @return observable execution mode
	 */
	ObservableExecutionMode observableExecutionMode() default ObservableExecutionMode.EAGER;

	/**
	 * When includes RUNTIME_EXCEPTION, any exceptions that are not ignored are
	 * wrapped in HystrixRuntimeException.
	 *
	 * @return exceptions to wrap
	 */
	HystrixException[] raiseHystrixExceptions() default {};

	/**
	 * Specifies default fallback method for the command. If both
	 * {@link #fallbackMethod} and {@link #defaultFallback} methods are
	 * specified then specific one is used. note: default fallback method cannot
	 * have parameters, return type should be compatible with command return
	 * type.
	 *
	 * @return the name of default fallback method
	 */
	String defaultFallback() default "";
}
